<template>
  <tm-sheet :margin="[0, 0]" :padding="[0, 0]">
    <view v-if="props.quickBtn.length > 0">
      <tm-text _class="py-24  px-16" color="grey" label="快捷方式"></tm-text>
      <view class="flex flex-row flex-row-top-start flex-wrap">
        <tm-tag
          :color="props.color"
          @click="quickChangeClick(item)"
          v-for="(item, index) in props.quickBtn"
          :key="index"
          text
          outlined
          :shadow="0"
          :label="item.label"
        ></tm-tag>
      </view>
    </view>
    <view class="flex flex-row flex-row-center-between mt-24 px-16 mb-32">
      <tm-text color="grey" label="自定时间范围"></tm-text>
      <tm-icon @click="clear" :font-size="24" color="grey" name="tmicon-delete"></tm-icon>
    </view>
    <view class="flex flex-row flex-row-center-center px-16">
      <tm-sheet
        text
        @click="changeFocus(0)"
        :round="24"
        class="flex-1"
        parenClass="flex-1"
        _class="flex flex-row flex-row-center-center"
        :color="focusIndex == 0 ? props.color : 'grey-4'"
        :height="76"
        outlined
        :border="4"
        :margin="[0, 0]"
        :padding="[32, 0]"
      >
        <view
          :userInteractionEnabled="false"
          style="width: 200rpx"
          class="flex flex-row flex-row-center-center"
        >
          <tm-text v-if="!valuedate_start_str" color="grey" label="开始时间"></tm-text>
          <tm-text
            v-if="valuedate_start_str"
            :color="focusIndex == 0 ? props.color : 'grey'"
            :label="valuedate_start_str"
          ></tm-text>
        </view>
      </tm-sheet>
      <view class="px-24">
        <tm-text :font-size="28" _class="text-weight-b" label="至"></tm-text>
      </view>
      <tm-sheet
        text
        @click="changeFocus(1)"
        :round="24"
        class="flex-1"
        parenClass="flex-1"
        _class="flex flex-row flex-row-center-center"
        :color="focusIndex == 1 ? props.color : 'grey-4'"
        :height="76"
        outlined
        :border="4"
        :margin="[0, 0]"
        :padding="[32, 0]"
      >
        <view
          :userInteractionEnabled="false"
          style="width: 200rpx"
          class="flex flex-row flex-row-center-center"
        >
          <tm-text v-if="!valuedate_end_str" color="grey" label="结束时间"></tm-text>
          <tm-text
            v-if="valuedate_end_str"
            :color="focusIndex == 1 ? props.color : 'grey'"
            :label="valuedate_end_str"
          ></tm-text>
        </view>
      </tm-sheet>
    </view>
    <view>
      <tm-time-view
        :showDetail="props.showDetail"
        :format="props.format"
        :immediateChange="props.immediateChange"
        :start="starTtime"
        :end="endTtime"
        @change="timeChange"
        v-model="picker_focus_date"
        :defaultValue="picker_focus_date"
      ></tm-time-view>
    </view>
    <view v-if="props.showBtn">
      <tm-button
        :color="props.color"
        @click="confirm"
        :round="24"
        :shadow="3"
        block
        label="确认"
      ></tm-button>
    </view>
  </tm-sheet>
</template>

<script lang="ts" setup>
import { ref, computed, nextTick, PropType, watch } from "vue";
import tmSheet from "@/tmui/components/tm-sheet/tm-sheet.vue";
import tmTag from "@/tmui/components/tm-tag/tm-tag.vue";
import tmText from "@/tmui/components/tm-text/tm-text.vue";
import tmIcon from "@/tmui/components/tm-icon/tm-icon.vue";
import tmButton from "@/tmui/components/tm-button/tm-button.vue";
import tmTimeView from "@/tmui/components/tm-time-view/tm-time-view.vue";
import * as dayjs from "../../tool/dayjs/esm/index";
const DayJs = dayjs.default;
interface showDetail {
  year: boolean;
  month: boolean;
  day: boolean;
  hour: boolean;
  minute: boolean;
  second: boolean;
}
interface quickBtnType {
  label: string;
  fun?: () => [string | number | Date | Da, string];
  color?: "primary";
  //这个是内部代号，如果提供了，上面的fun可以不用提供，且无效
  // br:本日，bz:本周,by:本月,jsy:近三个月,bn:本年,d7：近7天，d30:近30天
  type?: "br" | "bz" | "by" | "jsy" | "bn" | "d7" | "d30";
}
const props = defineProps({
  color: {
    type: String,
    default: "primary",
  },
  //需要展现的时间格式类型
  showDetail: {
    type: Object as PropType<showDetail>,
    default: () => {
      return {
        year: true,
        month: true,
        day: true,
        hour: false,
        minute: false,
        second: false,
      };
    },
  },
  //展示格式。最终影响到modelStr输出格式的内容。
  format: {
    type: String,
    default: "YYYY-MM-DD",
  },
  immediateChange: {
    type: Boolean,
    default: false,
  },
  quickBtn: {
    type: Array as PropType<Array<quickBtnType>>,
    default: () => {
      return [
        {
          label: "本日",
          fun: null,
          color: "primary",
          type: "br",
        },
        {
          label: "本周",
          fun: null,
          color: "primary",
          type: "bz",
        },
        {
          label: "本月",
          fun: null,
          color: "primary",
          type: "by",
        },
        {
          label: "近三月",
          fun: null,
          color: "primary",
          type: "jsy",
        },
        {
          label: "本年",
          fun: null,
          color: "primary",
          type: "bn",
        },
        {
          label: "近7天",
          fun: null,
          color: "primary",
          type: "d7",
        },
        {
          label: "近30天",
          fun: null,
          color: "primary",
          type: "d30",
        },
      ];
    },
  },
  start: {
    type: [String, Number, Date],
    default: new Date().setFullYear(new Date().getFullYear() - 1),
  },
  end: {
    type: [String, Number, Date],
    default: new Date().setFullYear(new Date().getFullYear() + 1),
  },
  defaultValue: {
    type: Array as PropType<Array<String | Number | Date>>,
    default: () => [],
  },
  modelValue: {
    type: Array as PropType<Array<String | Number | Date>>,
    default: () => [],
  },
  /** 当改变日期时，是否需要同步到vmodel变量中，立即执行双向同步，如果为false日期的改变不会同步到vmodel中
   * 然后需要你自行调用refs.getNowDate()来获取或者触发同步数据
   * 这里设置的意义是：当你需要同步日期数据，由用户设置时，如果你设置了一个确认按钮来同步用户设置的日期，那么这里可以设置为fase，
   * 然后你自行添加 一个确认按钮来触发refs.getNowDate()来同步数据，以执行用户的确认时间，否则不会同步。
   */
  asyncModel: {
    type: Boolean,
    default: true,
  },
  showBtn: {
    type: Boolean,
    default: true,
  },
});
const emits = defineEmits(["change", "update:modelValue", "confirm", "clear"]);
const valuedate_start = ref("");
const valuedate_end = ref("");
const focusIndex = ref(-1);
const picker_focus_date = ref("");
const defaultFormat = "YYYY/MM/DD HH:mm:ss";
let tid = NaN;
/** 开始时间 */
const starTtime = ref(DayJs(props.start).format(defaultFormat));
/** 结束时间 */
const endTtime = ref(DayJs(props.end).format(defaultFormat));
setDate(props.defaultValue);
watch(
  () => props.modelValue,
  () => {
    tid = setTimeout(() => {
      setDate(props.modelValue);
    }, 100);
  },
  { deep: true }
);
const valuedate_start_str = computed(() => {
  if (!valuedate_start.value) return "";
  return DayJs(valuedate_start.value).format(props.format);
});
//默认进入页面是选中开始的,就要赋值默认值.
// valuedate_start.value = valuedate_start_str.value
const valuedate_end_str = computed(() => {
  if (!valuedate_end.value) return "";
  return DayJs(valuedate_end.value).format(props.format);
});
function changeFocus(index: number) {
  focusIndex.value = index;
  let vstd = valuedate_start.value;
  let vsed = valuedate_end.value;

  if (index == 0 && !valuedate_start.value) {
    vstd = valuedate_end.value || DayJs().format(defaultFormat);
  }
  if (index == 1 && !valuedate_end.value) {
    vsed = valuedate_start.value || DayJs().format(defaultFormat);
  }

  setDate([vstd, vsed]);
}
function timeChange(evt: string) {
  if (focusIndex.value == -1) focusIndex.value = 0;

  if (focusIndex.value == 0) {
    valuedate_start.value = DayJs(evt).format(defaultFormat);
  } else if (focusIndex.value == 1) {
    valuedate_end.value = DayJs(evt).format(defaultFormat);
  }
  // #ifdef APP-NVUE
  checkTimeVaild();
  let nst = DayJs(valuedate_start.value).isValid()
    ? DayJs(valuedate_start.value).format(props.format)
    : "";
  let ese = DayJs(valuedate_end.value).isValid()
    ? DayJs(valuedate_end.value).format(props.format)
    : "";
  if (props.asyncModel) {
    emits("update:modelValue", [nst, ese]);
  }
  nextTick(() => {
    emits("change", [nst, ese]);
  });
  // #endif

  // #ifndef APP-NVUE
  nextTick(() => {
    checkTimeVaild();
    let nst = DayJs(valuedate_start.value).isValid()
      ? DayJs(valuedate_start.value).format(props.format)
      : "";
    let ese = DayJs(valuedate_end.value).isValid()
      ? DayJs(valuedate_end.value).format(props.format)
      : "";
    if (props.asyncModel) {
      emits("update:modelValue", [nst, ese]);
    }
    nextTick(() => {
      emits("change", [nst, ese]);
    });
  });
  // #endif
}

//检查两个时间的正确性,就是后者要大于前者.
function checkTimeVaild() {
  if (valuedate_end.value.length == 0 || valuedate_start.value.length == 0) return;
  if (focusIndex.value == 0) {
    if (DayJs(valuedate_start.value).isAfter(valuedate_end.value, "second")) {
      valuedate_end.value = valuedate_start.value;
    }
  }
  if (focusIndex.value == 1) {
    if (DayJs(valuedate_end.value).isBefore(valuedate_start.value, "second")) {
      valuedate_start.value = valuedate_end.value;
    }
  }
}

function quickChangeClick(item: quickBtnType) {
  let dstr = [];
  let typesar = ["br", "bz", "by", "jsy", "bn", "d7", "d30"];
  if (typeof item?.type === "string" && typesar.includes(item?.type)) {
    let str = item?.type ?? "";
    if (str == "br") {
      dstr = [DayJs().format(), DayJs().format()];
    } else if (str == "bz") {
      let dt = DayJs();
      dstr = [
        dt.startOf("week").subtract(1, "day").format(),
        dt.endOf("week").subtract(1, "day").format(),
      ];
    } else if (str == "by") {
      let dt = DayJs();
      dstr = [dt.startOf("month").format(), dt.endOf("month").format()];
    } else if (str == "jsy") {
      let dt = DayJs();
      dstr = [
        dt.startOf("month").subtract(2, "month").format(),
        dt.endOf("month").format(),
      ];
    } else if (str == "bn") {
      let dt = DayJs();
      dstr = [dt.startOf("year").format(), dt.endOf("year").format()];
    } else if (str == "d7") {
      let dt = DayJs();
      dstr = [dt.subtract(6, "day").format(), dt.format()];
    } else if (str == "d30") {
      let dt = DayJs();
      dstr = [dt.subtract(29, "day").format(), dt.format()];
    }
  } else {
    if (typeof item?.fun == "function") {
      dstr = item.fun();
      if (typeof idstr == "function") {
        dstr = dstr();
      }
    }
  }
  if (Array.isArray(dstr)) {
    if (dstr.length !== 2) return;

    valuedate_start.value = DayJs(dstr[0]).format(defaultFormat);
    valuedate_end.value = DayJs(dstr[1]).format(defaultFormat);
    if (focusIndex.value == -1) {
      focusIndex.value = 0;
    }
    if (focusIndex.value == 0) {
      picker_focus_date.value = valuedate_start.value;
    }
    if (focusIndex.value == 1) {
      picker_focus_date.value = valuedate_end.value;
    }
  }
}

function setDate(ar: Array<String | Number | Date>) {
  if (Array.isArray(ar)) {
    if (ar.length == 2) {
      valuedate_start.value = DayJs(ar[0]).isValid()
        ? DayJs(ar[0]).format(defaultFormat)
        : "";
      valuedate_end.value = DayJs(ar[1]).isValid()
        ? DayJs(ar[1]).format(defaultFormat)
        : "";
      focusIndex.value = focusIndex.value == -1 ? 0 : focusIndex.value;

      if (!DayJs(ar[focusIndex.value]).isValid()) return;
      picker_focus_date.value = DayJs(ar[focusIndex.value]).format(defaultFormat);
    }
  }
}
function confirm() {
  let nst = valuedate_start.value
    ? DayJs(valuedate_start.value).format(props.format)
    : "";
  let ese = valuedate_end.value ? DayJs(valuedate_end.value).format(props.format) : "";
  emits("update:modelValue", [nst, ese]);
  emits("confirm", [nst, ese]);
}
function getNowDate(): [string, string] {
  let nst = valuedate_start.value
    ? DayJs(valuedate_start.value).format(props.format)
    : "";
  let ese = valuedate_end.value ? DayJs(valuedate_end.value).format(props.format) : "";
  emits("update:modelValue", [nst, ese]);
  return [nst, ese];
}
function clear() {
  valuedate_start.value = "";
  valuedate_end.value = "";
  emits("clear");
}
defineExpose({ getNowDate });
</script>

<style></style>
